# coding=utf-8
__author__ = 'liubin'

import simplejson as json
from sqlalchemy.orm.collections import InstrumentedList
from .common import EXECUTOR, to_json
from .json import underscore_to_camel, camel_to_underscore, change_dict_naming_convention

def json_load_hook(d):
    """
    json读取时特殊处理
    把js用的大小写命名的key转换成py用的下划线分割的key
    """
    return change_dict_naming_convention(d, camel_to_underscore)

class HandlerMixin(object):
    """
    为了使用sqlalchemy而追加在handker上的mixin
    """
    def get_current_user(self):
        """
        获取当前用户CODE
        """
        user_id = self.get_secure_cookie("user")
        if user_id:
            # bytes 转 string
            user_id = user_id.decode()
        return user_id

    def on_finish(self):
        """
        重新 handler的on_finish
        """
        #print('close')
        try:
            #pass
            #print(self.db_conn)
            # print(self.db_conn.dirty)
            # if self.db_conn.dirty:
            self.db_conn.rollback()
        finally:
            self.db_conn.remove()

    def prepare(self):
        """
        执行前的准备
        """

        # 获取json_args
        content_type = self.request.headers.get('Content-Type')
        if content_type and content_type.startswith('application/json'):
            self.json_args = json.loads(self.request.body, encoding='utf-8',
                    object_hook=json_load_hook)
        else:
            self.json_args = None

        # 异步必须的参数
        self.executor = EXECUTOR


class ApiMixin(object):
    """
    使用Json Api的mixin
    """
    def success(self, data, **pairs):
        """
        重新定义 handler的success
        """
        data = to_json(data)
        res = {'success': True, 'data': data}
        if pairs:
            res.update(pairs)
        else:
            # 为了支援schema.validate使用以下方法
            # success(self, data: { data, pairs }):
            print('data')
            print(data)
            if data and 'pairs' in data and 'data' in data:
                res = {'success': True, 'data': data.data}
                res.update(data.pairs)
        self.write(res)
        self.finish()

    def fail(self, data):
        """
        重新定义handler的fail
        """
        data = to_json(data)
        res = {'success': False, 'data': data}
        self.write(res)
        self.finish()

    def error(self, message, data=None, code=None):
        """
        重新定义handler的error
        """
        res = {'success': False, 'message': message}
        if data:
            res['data'] = data
        if code:
            res['code'] = code
        self.write(res)
        self.finish()


class JsonpickleMixin(object):
    """
    为了使用Jsonpickle而追加在model上的mixin
    """
    def __getstate__(self):
        '''
        重写model的__getstate__
        :return:
        '''
        state = self.__dict__.copy()
        del state['_sa_instance_state']
        # InstrumentedList的特殊处理(backref相关)
        if type(state) == dict:
            for key, value in state.items():
                if type(value) == InstrumentedList:
                    data = []
                    for item in value:
                        data.append(item.__getstate__())
                    state[key] = data
        #underscore_to_camel
        state = change_dict_naming_convention(state, underscore_to_camel)
        return state
